package com.partition.mysql.utils;


import com.partition.mysql.em.RangeStrategyEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期工作对象
 *
 * @author Chunjie He
 * @version 1.0.0
 * @since 1.7
 */
public class DateUtils {

	/**
	 * 日志对象
	 */
	private final static Logger logger = LoggerFactory.getLogger(DateUtils.class);



	/**
	 * 一天的毫秒数
	 */
	public final static long ONE_DAY_LONG = 86400000;

	/**
	 * 日期格式字符串
	 */
	public final static String YYYYMMDD = "yyyyMMdd";
	public final static String YYYYMM = "yyyyMM";
	public final static String YYYY = "yyyy";


	/**
	 * 日期格式字符串
	 */
	public final static String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";


	/**
	 * 当日开始时间
	 *
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static Long todayStart(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}

	/**
	 * 当日结束时间
	 *
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static Long todayEnd(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTimeInMillis();
	}
	/**
	 * 当日结束时间
	 *
	 * @return
	 * @throws ParseException
	 */
	public static Long todayEnd() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTimeInMillis();
	}
	/**
	 * 昨日开始时间
	 *
	 * @return
	 * @throws ParseException
	 */
	public static Long toYesterdayStart() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}

	/**
	 * 上月开始时间
	 *
	 * @return
	 * @throws ParseException
	 */
	public static Long getLastMonthFirstDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, -1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}

	/*
	 *当月的第一天
	 */
	public static Long getCurrentMonthStartDay(){

		Date date = new Date();
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		//获得本月第一天
		calendar.add(Calendar.MONTH, 0);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTimeInMillis();
	}

	/*
	 *当年的最后一天
	 */
	public static Long getYearEndDay(Integer amount){
		Date date = new Date();
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		if (amount == null) {
			calendar.add(Calendar.YEAR, 0);
		}else {
			calendar.add(Calendar.YEAR, amount);
		}
		//获得12月最后一天
		calendar.set(Calendar.MONTH, 11);
		calendar.set(Calendar.DAY_OF_MONTH, 31);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTimeInMillis();
	}

	/*
	*当月的最后一天
	*/
	public static Long getMonthEndDay(Integer amount){
		Date date = new Date();
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		if (amount == null) {
			calendar.add(Calendar.MONTH, 0);
		}else {
			calendar.add(Calendar.MONTH, amount);
		}
		//获得本月最后一天
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return calendar.getTimeInMillis();
	}

	/**
	 * 当前日期加减天数
	 *
	 * @param day 天数
	 * @return Date Date
	 */
	public static Long getDayEnd(Integer day) {
		Calendar calendar=Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)+day);//让日期加1
		//加1之后的日期Top
		return calendar.getTimeInMillis();
	}

	/**
	 * 当前日期加减天数
	 *
	 * @param day 天数
	 * @return Date Date
	 */
	public static Date getDateSubDay(int day) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DATE, day);
		return cal.getTime();
	}

	/*
	* 根据类型和天数获取分区名和时间戳
	 * @param type策略类型
	 * @param nums结束点
	*/
	public static Map<String,Long> getDateMap(String type,Integer nums) {
		return getDateMap(type,0,nums);
	}

	/*
	 * 根据类型和天数获取分区名和时间戳
	 * @param type策略类型
	 * @param startNums开始点
	 * @param endNums结束点
	 */
	public static Map<String,Long> getDateMap(String type,Integer startNums,Integer endNums) {
		Map<String, Long> map = new TreeMap<>();
		if (RangeStrategyEnum.DAY.getCode().equals(type)){
			SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDD);
			for (int i = startNums; i <= endNums; i++) {
				Long endDay = getDayEnd(i);
				map.put(sdf.format(endDay),endDay);
			}
		}else if (RangeStrategyEnum.YEAR.getCode().equals(type)){
			SimpleDateFormat sdf = new SimpleDateFormat(YYYY);
			for (int i = startNums; i <= endNums; i++) {
				Long endDay = getYearEndDay(i);
				map.put(sdf.format(endDay),endDay);
			}
		}else {
			SimpleDateFormat sdf = new SimpleDateFormat(YYYYMM);
			for (int i = startNums; i <= endNums; i++) {
				Long endDay = getMonthEndDay(i);
				map.put(sdf.format(endDay),endDay);
			}
		}

		return map;
	}



	/**
	 * 通过秒毫秒数判断两个时间的间隔的天数
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDaysByMillisecond(Long date1,Long date2)
	{
		int days = (int) ((date1 - date2) / ONE_DAY_LONG);
		return days;
	}

	/**
	 * 获取两个日期相差的月数
	 */
	public static Integer getMonthDiff(Long d1, Long d2){
		return getMonthDiff(new Date(d1),new Date(d2));
	}
	/**
	 * 获取两个日期相差的月数
	 */
	public static Integer getMonthDiff(Date d1, Date d2) {
		Calendar c1 = Calendar.getInstance();
		Calendar c2 = Calendar.getInstance();
		c1.setTime(d1);
		c2.setTime(d2);
		int year1 = c1.get(Calendar.YEAR);
		int year2 = c2.get(Calendar.YEAR);
		int month1 = c1.get(Calendar.MONTH);
		int month2 = c2.get(Calendar.MONTH);
		int day1 = c1.get(Calendar.DAY_OF_MONTH);
		int day2 = c2.get(Calendar.DAY_OF_MONTH);
		// 获取年的差值?
		int yearInterval = year1 - year2;
		// 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
		if (month1 < month2 || month1 == month2 && day1 < day2) {
			yearInterval--;
		}
		// 获取月数差值
		int monthInterval = (month1 + 12) - month2;
		if (day1 < day2) {
			monthInterval--;
		}
		monthInterval %= 12;
		int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
		return monthsDiff;
	}


	public static void main(String[] args) {
		int months = 3;

		SimpleDateFormat sdf = new SimpleDateFormat(STANDARD_FORMAT);

		for (int i = 0; i <= months; i++) {
			Long currentMonthEndDay = getDayEnd(i);
			System.out.println("currentMonthEndDay = " + currentMonthEndDay);
		}
		Long time =1649951999999L;
		long l = time - getDayEnd(0);
		System.out.println(l/ONE_DAY_LONG);
	}
}
